#ifndef __SW_SPI_H__
#define __SW_SPI_H__

/* Include -------------------------------------------------------------------*/
#include <stdint.h>

/* Public define -------------------------------------------------------------*/
#define SPI_DEV_FIND            1u         /*! Find spi device object */

/**
 * spi error infomation definition
 */ 
typedef enum
{
    SPI_SUCCESS = 0, /*! Not error   */
    SPI_TIMEOUT,     /*! ack timeout */
} SPI_Error_t;

typedef enum
{
    SPI_MODE_0 = 0,  /*! CPOL=0, CPHA=0 */
    SPI_MODE_1,      /*! CPOL=0, CPHA=1 */
    SPI_MODE_2,      /*! CPOL=1, CPHA=0 */
    SPI_MODE_3       /*! CPOL=1, CPHA=1 */
} SPI_Mode_t;

typedef enum
{
    SPI_MSB_FIRST = 0, /*! MSB first */
    SPI_LSB_FIRST      /*! LSB first */
} SPI_BitOrder_t;

/**
 * spi gpio optinos struct definition
 */ 

typedef struct
{
    void (*sdo_low)(void);              /*! Set spi sdo pin low level     */
    void (*sdo_high)(void);             /*! Set spi sdo pin high level    */
    void (*sck_low)(void);              /*! Set spi sck pin low level     */
    void (*sck_high)(void);             /*! Set spi sck pin high level    */
    uint8_t (*sdi_read_level)(void);    /*! Read spi sdi pin level        */
    void (*cs_low)(void);               /*! Set spi cs pin low level      */
    void (*cs_high)(void);              /*! Set spi cs pin high level     */
} spi_ops_t;

/**
 * spi driver struct definition
 */
struct sw_spi_dev
{
    spi_ops_t ops;                       /*! spi ops interface    */
    uint16_t mode;                       /*! spi mode             */
    uint16_t bit_order;                  /*! spi bit order        */
    uint32_t speed;                      /*! control i2c bus speed */
    void (*delay_us)(uint32_t);
#if (SPI_DEV_FIND > 0u)                  /*! if enable device find */
    const char *name;                    /*! i2c device name       */
    struct sw_spi_dev *next;             /*! For the linked list   */
#endif
};
typedef struct sw_spi_dev sw_spi_dev_t;
typedef struct sw_spi_dev * sw_spi_dev_pt;

/**
 * SPI transport message struct
 */
struct sw_spi_msg
{
    uint16_t len;                       /*! transport buffer size */
    uint8_t *buf;                       /*! transport byte buffer */
};
typedef struct sw_spi_msg sw_spi_msg_t;


/* Exported functions --------------------------------------------------------*/
void         sw_spi_init(struct sw_spi_dev *dev);
#if (SPI_DEV_FIND > 0u)
struct sw_spi_dev * sw_spi_dev_find(const char* name);
#endif

uint8_t sw_spi_transfer_byte(struct sw_spi_dev *dev, uint8_t byte);
void sw_spi_transfer(struct sw_spi_dev *dev, sw_spi_msg_t *msgs);


#endif /* __SW_SPI_H__ */













